From feab19da93131b8a52339b740b57c226fa87c0cf Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Mon, 29 Aug 2005 11:20:15 +0000 Subject: [PATCH] improved memory wrapper functions --- ChangeLog | 12 +++ babl/babl-internal.c | 2 + babl/babl-memory.c | 177 ++++++++++++++++++++++++++++++++++++------- babl/babl-memory.h | 25 +++--- babl/babl-util.c | 2 +- babl/babl.c | 2 + 6 files changed, 183 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index bfbd6f1..cbc40c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2005-08-29 Øyvind Kolås + + * babl/babl-internal.c: (babl_internal_init): set memory functions. + * babl/babl-memory.c: (babl_set_malloc), (babl_set_free), + (functions_sanity), (babl_malloc), (babl_free), (babl_realloc), + (babl_calloc), (babl_sizeof), (babl_strdup), (babl_strcat), + (babl_memory_sanity), + * babl/babl-memory.h: Added babl_str* functions, that behave slightly + different from the standard ones. + * babl/babl-util.c: (babl_add_ptr_to_list): made error fatal. + * babl/babl.c: (babl_init), (babl_destroy): added babl_internal + 2005-08-28 Øyvind Kolås * babl/babl-internal.[ch]: (babl_die): A function to call from diff --git a/babl/babl-internal.c b/babl/babl-internal.c index 8eba491..f19e5b7 100644 --- a/babl/babl-internal.c +++ b/babl/babl-internal.c @@ -71,6 +71,8 @@ babl_die (void) void babl_internal_init (void) { + babl_set_malloc (malloc); + babl_set_free (free); } void diff --git a/babl/babl-memory.c b/babl/babl-memory.c index 3f2b5d4..b4fa769 100644 --- a/babl/babl-memory.c +++ b/babl/babl-memory.c @@ -23,6 +23,24 @@ #include #include "babl-internal.h" +static void *(* malloc_f) (size_t size) = malloc; +static void (* free_f) (void *ptr) = free; + +static void *first_malloc_used = NULL; +static void *first_free_used = NULL; + +void +babl_set_malloc (void *(* malloc_function) (size_t size)) +{ + malloc_f = malloc_function; +} + +void +babl_set_free (void (* free_function) (void *ptr)) +{ + free_f = free_function; +} + static char *signature = "So long and thanks for all the fish."; typedef struct @@ -36,6 +54,7 @@ typedef struct #define BAI(ptr) ((BablAllocInfo*)(((void*)ptr)-OFFSET)) #define IS_BAI(ptr) (BAI(ptr)->signature == signature) +/* runtime statistics: */ static int mallocs = 0; static int frees = 0; static int strdups = 0; @@ -52,13 +71,37 @@ mem_stats (void) return buf; } +static void +functions_sanity (void) +{ + if (first_malloc_used != malloc_f || + first_free_used != free_f) + { + if (first_malloc_used == NULL) + { + first_malloc_used = malloc_f; + first_free_used = free_f; + } + else + { + babl_fatal ("babl memory function(s) attempted switched on the fly"); + } + } +} + +/* Allocate /size/ bytes of memory + * + * contents of memory undefined. + */ void * babl_malloc (size_t size) { void *ret; - assert (size); - ret = malloc (size + OFFSET); + assert (size); + + functions_sanity (); + ret = malloc_f (size + OFFSET); if (!ret) babl_log ("args=(%i): failed", size); @@ -68,21 +111,10 @@ babl_malloc (size_t size) return ret + OFFSET; } -char * -babl_strdup (const char *s) -{ - char *ret; - - ret = babl_malloc (strlen (s)+1); - if (!ret) - babl_log ("args=(%s): failed", s); - strcpy (ret, s); - - strdups++; - mallocs--; - return ret; -} - +/* Create a duplicate allocation of the same size, note + * that the exact location of the allocation needs to be + * passed. + */ void * babl_dup (void *ptr) { @@ -98,16 +130,23 @@ babl_dup (void *ptr) return NULL; } +/* Free memory allocated by a babl function (note: babl_free + * will complain if memory not allocated by babl is passed.) + */ void babl_free (void *ptr) { if (!ptr) return; assert(IS_BAI(ptr)); - free (BAI(ptr)); + functions_sanity (); + free_f (BAI(ptr)); frees++; } +/* reallocate allocation to be in size instead, contents of + * common allocated memory between old and new size is preserved. + */ void * babl_realloc (void *ptr, size_t size) @@ -120,18 +159,32 @@ babl_realloc (void *ptr, } assert (IS_BAI (ptr)); - ret = realloc (BAI(ptr), size + OFFSET); + + if (size==0) + { + babl_free (ptr); + return NULL; + } + if (babl_sizeof (ptr) >= size) + { + return ptr; + } + else if (babl_sizeof (ptr) < size) + { + ret = babl_malloc (size); + memcpy (ret, ptr, babl_sizeof (ptr)); + babl_free (ptr); + reallocs++; + return ret; + } if (!ret) - babl_log ("args=(%p, %i): failed", ptr, size); + babl_fatal ("args=(%p, %i): failed", ptr, size); - BAI(ret+OFFSET)->signature = signature; - BAI(ret+OFFSET)->size = size; - - reallocs++; - return ret + OFFSET; + return NULL; } +/* allocate nmemb*size bytes and set it to all zeros. */ void * babl_calloc (size_t nmemb, size_t size) @@ -139,7 +192,7 @@ babl_calloc (size_t nmemb, void *ret = babl_malloc (nmemb*size); if (!ret) - babl_log ("args=(%i, %i): failed", nmemb, size); + babl_fatal ("args=(%i, %i): failed", nmemb, size); memset (ret, 0, nmemb*size); @@ -148,7 +201,75 @@ babl_calloc (size_t nmemb, return ret; } -void +/* Returns the size of an allocation. + */ +size_t +babl_sizeof (void *ptr) +{ + assert (IS_BAI (ptr)); + return BAI(ptr)->size; +} + +/* duplicate allocation needed for a string, and + * copy string contents, string is zero terminated. + */ +char * +babl_strdup (const char *s) +{ + char *ret; + + ret = babl_malloc (strlen (s)+1); + if (!ret) + babl_log ("args=(%s): failed", s); + strcpy (ret, s); + + strdups++; + mallocs--; + return ret; +} + +/* append string to babl allocated string dest, the returned + * string is the new canonical position with src added to dest + * if the dest allocation needed to be resized. Passing NULL + * causes a new allocation (thus babl-memory sees NULL as the empty + * string). + */ +char * +babl_strcat (char *dest, + const char *src) +{ + char *ret; + int src_len; + int dst_len; + + src_len = strlen (src); + if (!dest) + { + ret = babl_malloc (src_len+1); + strcpy (ret, src); + return ret; + } + assert (IS_BAI (dest)); + dst_len = strlen (dest); + + ret = dest; + + if (babl_sizeof (dest) < src_len + dst_len + 1) + { + size_t new_size = babl_sizeof (dest); + while (new_size < src_len + dst_len + 1) + new_size*=2; + ret = babl_realloc (dest, new_size); + } + + strcpy (&ret[dst_len], src); + return ret; +} + +/* performs a sanity check on memory, (checks if number of + * allocations and frees on babl memory evens out to zero). + */ +int babl_memory_sanity (void) { if (frees != mallocs + strdups + callocs) @@ -157,5 +278,7 @@ babl_memory_sanity (void) "%s\n" "\tbalance: %i-%i=%i\n", mem_stats(), (strdups+mallocs+callocs),frees, (strdups+mallocs+callocs)-frees); + return -1; } + return 0; } diff --git a/babl/babl-memory.h b/babl/babl-memory.h index 6465b91..170e566 100644 --- a/babl/babl-memory.h +++ b/babl/babl-memory.h @@ -20,16 +20,23 @@ #ifndef _BABL_MEMORY_H #define _BABL_MEMORY_H -void * babl_malloc (size_t size); -void babl_free (void *ptr); +void babl_set_malloc (void *(*malloc_function) (size_t size)); +void babl_set_free (void (*free) (void *ptr)); +int babl_memory_sanity (void); -void * babl_realloc (void *ptr, - size_t size); +void * babl_malloc (size_t size); +void babl_free (void *ptr); +void * babl_calloc (size_t nmemb, + size_t size); +void * babl_realloc (void *ptr, + size_t size); + +size_t babl_sizeof (void *ptr); +void * babl_dup (void *ptr); + +char * babl_strdup (const char *s); +char * babl_strcat (char *dest, + const char *src); -void * babl_calloc (size_t nmemb, - size_t size); -char * babl_strdup (const char *s); -void * babl_dup (void *ptr); -void babl_memory_sanity (void); #endif diff --git a/babl/babl-util.c b/babl/babl-util.c index 3d40fe8..8df5839 100644 --- a/babl/babl-util.c +++ b/babl/babl-util.c @@ -53,7 +53,7 @@ babl_add_ptr_to_list (void ***list, if (!(*list)) { - babl_log ("failed to realloc"); + babl_fatal ("failed to realloc"); } (*list)[orig_len]=new; diff --git a/babl/babl.c b/babl/babl.c index d657326..3d0dd1d 100644 --- a/babl/babl.c +++ b/babl/babl.c @@ -30,6 +30,7 @@ babl_init (void) { if (ref_count++==0) { + babl_internal_init (); babl_type_init (); babl_sampling_init (); babl_component_init (); @@ -58,6 +59,7 @@ babl_destroy (void) babl_component_destroy (); babl_sampling_destroy (); babl_type_destroy (); + babl_internal_destroy (); babl_memory_sanity (); } } -- 2.30.2